<?php

declare(strict_types=1);

namespace App\Model;

use App\Constants\ErrorCode;
use App\Exception\ApiException;
use App\Helpers\ConfigUtil;
use App\Helpers\YzhUtil;
use Hyperf\DbConnection\Model\Model;

/**
 * 提现申请
 */
class Withdraw extends Model
{
    protected $table = 'user_withdraw';
    protected $fillable = ['status', 'yzh_detail'];

    //首次提现倍数
    const FIRST_WITHDRAW_UNIT = 1;
    //提现整数倍
    const WITHDRAW_UNIT = 100;
    //单日提现上线
    const WITHDRAW_DAY_MAX = 2000;

    //待审核
    const STATUS_ING = 0;
    //审核通过
    const STATUS_OK = 1;
    //审核不通过
    const STATUS_FAIL = 2;
    //云账户提现异常
    const STATUS_YZH_ERR = 3;

    //银行提现
    const WITHDRAW_TYPE_BANK = 1;

    //支付宝提现
    const WITHDRAW_TYPE_ALI = 2;


    /**
     * 提现列表
     */
    const WITHDRAW_LIST = [
        ['rmb' => 5, 'cost_coin' => 50, 'is_new' => 1],
        ['rmb' => 10, 'cost_coin' => 100, 'is_new' => 0],
        ['rmb' => 50, 'cost_coin' => 500, 'is_new' => 0],
        ['rmb' => 200, 'cost_coin' => 2000, 'is_new' => 0],
        ['rmb' => 500, 'cost_coin' => 5000, 'is_new' => 0],
        ['rmb' => 1000, 'cost_coin' => 10000, 'is_new' => 0],
        ['rmb' => 2000, 'cost_coin' => 20000, 'is_new' => 0],
        // ['rmb' => 5000, 'cost_coin' => 50000],
    ];

    /**
     * 检查提现金额是否在指定列表中
     */
    static function checkCostCoin($rmb = 0)
    {
        foreach (self::WITHDRAW_LIST as $item) {
            if ($rmb == $item['rmb']) return $item['cost_coin'];
        }
        return 0;
    }

    static function getStatus($status = self::STATUS_ING)
    {
        $allStatus = [
            self::STATUS_ING => '审核中',
            self::STATUS_OK => '已处理',
            self::STATUS_FAIL => '审核不通过',
            self::STATUS_YZH_ERR => '提现异常'
        ];
        return $allStatus[$status] ?? '未知状态';
    }

    /**
     * 添加记录
     */
    static function addRecord($userId = 0, $withdrawRmb = 0, $withdrawCoin = 0)
    {
        if (!$userId) return 0;
        $model = new self();
        $model->status = self::STATUS_ING;
        $model->user_id = $userId;
        $model->withdraw_rmb = $withdrawRmb;
        $model->withdraw_coin = $withdrawCoin;
        return $model->saveOrFail() ? 1 : 0;
    }

    /**
     * 查找用户提现记录
     */
    static function checkFirst($userId = 0)
    {
        $status = [self::STATUS_ING, self::STATUS_OK];
        return self::where('user_id', $userId)->whereIn('status', $status)->orderBy('id', 'desc')->first();
    }

    /**
     * 查找用户提现记录
     */
    static function checkTodayCount($userId = 0)
    {
        $status = [self::STATUS_ING, self::STATUS_OK];
        $where = [
            ['user_id', $userId],
            ['created_at', '>', date('Y-m-d')]
        ];
        return self::where($where)->whereIn('status', $status)->count();
    }

    /**
     * 计算用户最大可提现金额
     * @param $incomeCoin 当前收入账户金币数
     */
    static function getMaxRmbLimit($userId = 0, $incomeCoin = 0)
    {
        $maxCoinLmt = $incomeCoin * (1 - ConfigUtil::getWithdrawRate());
        return floor($maxCoinLmt / ConfigUtil::getCoinRate());
    }

    /**
     * 提现记录列表
     */
    static function getList($userId = 0, $page = 1, $pageNum = 20)
    {
        $where = [
            'user_id' => $userId,
        ];
        $start = ($page - 1) * $pageNum;
        return self::where($where)->orderBy('id', 'desc')->offset($start)->limit($pageNum)->get()->toArray();
    }

    /**
     * 列表元素
     */
    static function buildItem($log = [])
    {
        $colors = ['#5D5D5D', '#1DD36E', '#F55363'];
        return [
            'title' => '申请提现',
            'desc' => "到账金额：{$log['withdraw_rmb']}",
            'status_desc' => self::getStatus($log['status']),
            'status_color' => $colors[$log['status']],
            'mark' => '',
            'time' => (string)$log['created_at']
        ];
    }

    /**
     * RMB转换成金币
     */
    static function transferToCoin($rmb = 0)
    {
        return ($rmb * ConfigUtil::getCoinRate()) / (1 - ConfigUtil::getWithdrawRate());
    }

    /**
     * 是否开始收取手续费
     */
    static function checkFeeStart($version = '')
    {
        return true;
        //$version >= env('WITHDRAW_VERSION', '1.3.1') && date('Y-m-d') >= env('WITHDRAW_DATE', '2022-02-01');
    }

    /**
     * 判断是否首次提现（包括设备)
     * @param int $userId
     * @param int $selectType 1-列表 2-提现时后判断是否有一条等待提现
     * @return bool|\Hyperf\Database\Model\Model|\Hyperf\Database\Query\Builder|object|null
     */
    static function checkFirstV2(int $userId, $selectType = 1)
    {
        $user = User::find($userId);
        if (empty($user)) {
            return false;
        }

        // 从03-13注册起才有秒到账
        $newGirlTaskValid = config('act.new_girl_task_valid', '2023-03-12');
        if ($user->created_at <= $newGirlTaskValid) {
            return false;
        }

        if (empty($user->oaid) && empty($user->imei)) {
            return false;
        }

        $oaIdUser = [];
        if ($user->oaid) {
            $oaIdUser = User::where('oaid', $user->oaid)->pluck('id')->toArray();
        }

        $imeiUser = [];
        if ($user->imei) {
            $imeiUser = User::where('imei', $user->imei)->pluck('id')->toArray();
        }

        $userId = array_merge([$userId], $oaIdUser, $imeiUser);

        if ($selectType == 1) {
            $status = [self::STATUS_ING, self::STATUS_OK];

            return self::whereIn('user_id', $userId)->whereIn('status', $status)->orderBy('id', 'desc')->first();
        } else {
            $status = [self::STATUS_ING];

            return self::whereIn('user_id', $userId)->whereIn('status', $status)->orderBy('id', 'desc')->first();
        }
    }

    /**
     * 处理秒到账逻辑
     * @param $userId
     * @param $packageWithdrawRmb
     * @return array|int[]
     */
    public static function withdrawMain($userId, $packageWithdrawRmb)
    {
        $secondsWithdraw = array_search($packageWithdrawRmb, array_column(self::WITHDRAW_LIST, 'rmb'));
        if (self::WITHDRAW_LIST[$secondsWithdraw]['is_new'] != 1) {
            return [
                'ret' => -1
            ];
        }

        $withdrawalObject = self::checkFirstV2($userId, 2);
        if (!$withdrawalObject) {
            return [
                'ret' => -1
            ];
        }

        $userInfo = User::where('id', $userId)->first();

        if($userInfo->status != 0 ){
            $str = $userInfo->status == 1 ? '该用户已被冻结，无法正常提现' : '该用户已注销，无法正常提现';

            throw new ApiException($str, ErrorCode::DEFAULT_ERROR);
        }

        $payWay = 'yzh';
        $status = Withdraw::STATUS_OK;
        $ret = self::doYzhOrder($withdrawalObject->toArray());

        $withdrawWay = isset($ret['bind_type']) && $ret['bind_type'] == self::WITHDRAW_TYPE_ALI ? '支付宝' : '银行卡';

        log_info(__CLASS__ . "WithdrawId:{$withdrawalObject->id}==subject:{$withdrawalObject->subject}==UserId:{$userId}==ret:" . json_encode($ret));

        //提现审核没有通过
        if ($ret['ret'] != 0) {
            throw new ApiException('秒到账失败，请待人工审核');
        }

        $time = date('Y年m月d日', strtotime((string)$withdrawalObject->created_at));
        $pushMsg = "你于{$time}申请的提现已通过审核，请注意查收你的银行卡/支付宝账号账号！";
        Message::pushOfficialMsg($userId, $pushMsg);

        Withdraw::where('id', $withdrawalObject->id)->limit(1)->update([
            'status'        => $status,
            'withdraw_way'  => $payWay,
            'sec_in_arrive' => 1
        ]);

        return [
            'ret' => 0,
            'msg' => $pushMsg
        ];
    }

    /**
     * 云账户下单
     * @param array $withdrawRecord
     * @return array
     */
    public static function doYzhOrder($withdrawRecord = [])
    {
        if (!$withdrawRecord) {
            return ['ret' => -1, 'message' => ""];
        }

        $userId = $withdrawRecord['user_id'];
        $payRmb = $withdrawRecord['withdraw_rmb'];

        $bindInfo = UserProfilePersonal::getBindInfo($userId, '');

        if (!$bindInfo) return ['ret' => -1, 'message' => '提现信息不存在，或者没有认证通过！'];
        $orderInfo = [
            'pay_money'  => $payRmb,
            'id_card'    => $bindInfo['id_card'],
            'real_name'  => $bindInfo['real_name'],
            'card_no'    => $bindInfo['card_no'],
            'notify_url' => config('yzh.notify_url'),
            'order_id'   => $orderId = YzhUtil::buildOrderId($userId),
        ];

        //是否支付宝
        $bindAliAccount = UserProfilePersonal::BIND_TYPE_ALI == $bindInfo['type'];

        //更新云账户订单ID
        Withdraw::where('id', $withdrawRecord['id'])->update([
            'yzh_order_id' => $orderId,
            //银行卡
            'account_type' => $bindAliAccount ? 0 : 1,
        ]);

//        return ['ret' => 0, 'message' => '已成功提交提现请求', 'bind_type' => $bindInfo['type']];

        if ($bindAliAccount) {
            $result = YzhUtil::orderAlipay($orderInfo);
        } else {
            $result = YzhUtil::orderBank($orderInfo);
        }

        if (isset($result['code']) && $result['code'] == '0000') {
            return ['ret' => 0, 'message' => '已成功提交提现请求', 'bind_type' => $bindInfo['type']];
        }

        log_info(__CLASS__."==withdrawRecordId:{$withdrawRecord['id']}==orderInfo:".json_encode($orderInfo)."==result:".json_encode($result));

        return ['ret' => -1, 'message' => "{$result['message']}; ErrCode:{$result['code']}", 'bind_type' => $bindInfo['type']];
    }
}
